﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using GiaoTrinhEPU.Repositories.Interfaces;
using GiaoTrinhEPU.Caching;
using GiaoTrinhEPU.Repositories.DataModels;

namespace GiaoTrinhEPU.Repositories.Repositories
{
    public class ExportRepository : BaseRepository, IExportRepository
    {
        public ExportRepository() : base() { }
        public ExportRepository(ICacheProvider cacheProvider) : base(cacheProvider) { }

        /// <summary>
        /// Clear cache of all banks
        /// </summary>
        public void ClearCache()
        {
            Cache.Invalidate("exports");
        }

        /// <summary>
        /// Clear cache of the export
        /// </summary>
        /// <param name="key"></param>
        public void ClearCache(String key)
        {
            Cache.Invalidate("export-" + key);
        }
        /// <summary>
        /// Create a new bank
        /// </summary>
        /// <param name="item"></param>
        public void CreateExport(Export item)
        {
            try
            {
                using (var db = new ThuVienEPUDataContext())
                {
                    db.Exports.InsertOnSubmit(item);
                    db.SubmitChanges();
                }
            }
            catch (Exception ex)
            {
                Logger.Writer.Write(ex.Message, ex.Source);
            }
        }

        // <summary>
        /// Update Export
        /// </summary>
        /// <param name="item"></param>
        public void UpdateExport(Export item)
        {
            try
            {
                using (var db = new ThuVienEPUDataContext())
                {
                    var export = db.Exports.Single(a => a.Id.Equals(item.Id));
                    export.Id = item.Id;
                    export.EDate = item.EDate;
                    export.Quantum = item.Quantum;
                    export.WarehouseId = item.WarehouseId;
                    export.Code = item.Code;
                    export.Description = item.Description;
                    db.SubmitChanges();
                }
            }
            catch (Exception ex)
            {
                Logger.Writer.Write(ex.Message, ex.Source);
            }
        }
        /// <summary>
        /// Delete a Export
        /// </summary>
        /// <param name="id"></param>
        public void DeleteExport(int id)
        {
            try
            {
                using (var db = new ThuVienEPUDataContext())
                {
                    var export = db.Exports.Single(a => a.Id.Equals(id));
                    db.Exports.DeleteOnSubmit(export);
                    db.SubmitChanges();
                }
            }
            catch (Exception ex)
            {
                Logger.Writer.Write(ex.Message, ex.Source);
            }
        }
        /// <summary>
        /// List all Export in database, order by Export's name
        /// </summary>
        /// <returns></returns>
        public IEnumerable<ExportModel> ListExports(bool cacheEnabled = true)
        {
            if (cacheEnabled == true)
            {
                // if it's not in the cache, we need to read it form the repository// First, check the cache
                IEnumerable<ExportModel> exportData = Cache.Get("exports") as IEnumerable<ExportModel>;

                // if it's not in the cache, we need to read it form the repository
                if (exportData == null)
                {
                    //Get the repository data
                    try
                    {
                        using (var db = new ThuVienEPUDataContext())
                        {
                            db.DeferredLoadingEnabled = false;
                            exportData = (from x in db.Exports
                                          join y in db.Warehouses
                                          on x.WarehouseId equals y.Id
                                          select new ExportModel
                                          {
                                              Id = x.Id,
                                              Code = x.Code,
                                              Description = x.Description,
                                              EDate = x.EDate,
                                              Quantum = x.Quantum,
                                              WarehouseName = y.Name
                                          }).OrderBy(a => a.Code).ToList();
                        }
                    }
                    catch (Exception ex)
                    {
                        Logger.Writer.Write(ex.Message, ex.Source);
                    }

                    if (exportData.Any())
                    {
                        Cache.Set("exports", exportData, GiaoTrinhEPU.Caching.Properties.Settings.Default.CacheTime);
                    }
                }
                return exportData;
            }
            else
            {
                //Get the repository data
                IEnumerable<ExportModel> exportData = null;

                try
                {
                    using (var db = new ThuVienEPUDataContext())
                    {
                        exportData = (from x in db.Exports
                                      join y in db.Warehouses
                                      on x.WarehouseId equals y.Id
                                      select new ExportModel
                                      {
                                          Id = x.Id,
                                          Code = x.Code,
                                          Description = x.Description,
                                          EDate = x.EDate,
                                          Quantum = x.Quantum,
                                          WarehouseName = y.Name
                                      }).OrderBy(a => a.Code).ToList();
                    }
                }
                catch (Exception ex)
                {
                    Logger.Writer.Write(ex.Message, ex.Source);
                }

                return exportData;
            }
        }
        /// <summary>
        /// Get a Export if we know it's id
        /// </summary>
        /// <param name="id">id of the banner</param>
        /// <returns>
        /// return a banner
        /// </returns>
        public Export GetExportById(int id)
        {
            Cache.Invalidate("export-" + id);
            Export exportData = Cache.Get("export-" + id) as Export;
            if (exportData == null)
            {
                try
                {
                    using (var db = new ThuVienEPUDataContext())
                    {
                        exportData = db.Exports.Single(a => a.Id.Equals(id));
                    }
                }
                catch (Exception ex)
                {
                    Logger.Writer.Write(ex.Message, ex.Source);
                }

                if (exportData != null)
                {
                    Cache.Set("export-" + id, exportData, GiaoTrinhEPU.Caching.Properties.Settings.Default.CacheTime);
                }
            }
            return exportData;
        }
        /// <summary>
        /// check name of the export already exist in database 
        /// </summary>
        /// <param name="name"></param>
        /// <returns>
        /// return true if exist, else false
        /// </returns>
        public bool HasNameExisted(string code)
        {
            bool isExisted = false;
            try
            {
                using (var db = new ThuVienEPUDataContext())
                {
                    var list = (from a in db.Exports
                                where a.Code.Equals(code)
                                select a.Id).ToList();
                    isExisted = list.Count > 0;
                }
            }
            catch (Exception ex)
            {
                Logger.Writer.Write(ex.Message, ex.Source);
            }
            return isExisted;
        }

        /// <summary>
        /// check duplication of the banner in case of updating the banner
        /// </summary>
        /// <param name="id"></param>
        /// <param name="name"></param>
        /// <returns></returns>
        public bool HasNameDuplicated(int id, string code)
        {
            bool isDuplicated = false;
            try
            {
                using (var db = new ThuVienEPUDataContext())
                {
                    var list = (from a in db.Exports
                                where a.Code.Equals(code)
                                where !a.Id.Equals(id)
                                select a.Id).ToList();
                    isDuplicated = list.Count > 0;
                }
            }
            catch (Exception ex)
            {

                Logger.Writer.Write(ex.Message, ex.Source);
            }
            return isDuplicated;
        }

    }
}
